﻿using System;
using System.Runtime.InteropServices;
using System.Drawing;

namespace com.reltru.GDI
{
    public enum PenStyle
    {
        PS_SOLID = 0,
        PS_DASH = 1,
        PS_DOT = 2,
        PS_DASHDOT = 3,
        PS_DASHDOTDOT = 4,
        PS_NULL = 5,
        PS_INSIDEFRAME = 6,
        PS_USERSTYLE = 7,
        PS_ALTERNATE = 8,
        PS_STYLE_MASK = 0x0000000F,
        PS_ENDCAP_ROUND = 0x00000000,
        PS_ENDCAP_SQUARE = 0x00000100,
        PS_ENDCAP_FLAT = 0x00000200,
        PS_ENDCAP_MASK = 0x00000F00,
        PS_JOIN_ROUND = 0x00000000,
        PS_JOIN_BEVEL = 0x00001000,
        PS_JOIN_MITER = 0x00002000,
        PS_JOIN_MASK = 0x0000F000,
        PS_COSMETIC = 0x00000000,
        PS_GEOMETRIC = 0x00010000,
        PS_TYPE_MASK = 0x000F0000
    }

    public enum StockObjects
    {
        WHITE_BRUSH = 0,
        LTGRAY_BRUSH = 1,
        GRAY_BRUSH = 2,
        DKGRAY_BRUSH = 3,
        BLACK_BRUSH = 4,
        NULL_BRUSH = 5,
        HOLLOW_BRUSH = NULL_BRUSH,
        WHITE_PEN = 6,
        BLACK_PEN = 7,
        NULL_PEN = 8,
        OEM_FIXED_FONT = 10,
        ANSI_FIXED_FONT = 11,
        ANSI_VAR_FONT = 12,
        SYSTEM_FONT = 13,
        DEVICE_DEFAULT_FONT = 14,
        DEFAULT_PALETTE = 15,
        SYSTEM_FIXED_FONT = 16,
        DEFAULT_GUI_FONT = 17,
        DC_BRUSH = 18,
        DC_PEN = 19,
    }

    class RGB
    {
        public int r, g, b;
        public RGB(int _r, int _g, int _b)
        {
            r = _r;
            g = _g;
            b = _b;
        }
    }

    class Drawing
    {
        //
        //
        // Interops
        //
        //

        [DllImport("gdi32.dll")]
        static extern IntPtr CreateHatchBrush(int fnStyle, uint clrref);

        [DllImport("gdi32.dll")]
        static extern IntPtr CreatePen(PenStyle fnPenStyle, int nWidth, uint crColor);

        [DllImport("gdi32.dll")]
        static extern IntPtr CreateRectRgn(int nLeftRect, int nTopRect, int nRightRect, int nBottomRect);

        [DllImport("gdi32.dll")]
        static extern IntPtr CreateSolidBrush(uint crColor);

        [DllImport("gdi32.dll")]
        static extern bool DeleteObject(IntPtr hObject);

        [DllImport("gdi32.dll")]
        static extern bool Ellipse(IntPtr hdc, int nLeftRect, int nTopRect, int nRightRect, int nBottomRect);

        [DllImport("gdi32.dll")]
        static extern bool FillRgn(IntPtr hdc, IntPtr hrgn, IntPtr hbr);

        [DllImport("gdi32.dll")]
        static extern IntPtr GetStockObject(StockObjects fnObject);

        [DllImport("gdi32.dll")]
        static extern bool LineTo(IntPtr hdc, int nXEnd, int nYEnd);

        [DllImport("gdi32.dll")]
        static extern bool MoveToEx(IntPtr hdc, int X, int Y, IntPtr lpPoint);

        [DllImport("gdi32.dll")]
        static extern bool Rectangle(IntPtr hdc, int nLeftRect, int nTopRect, int nRightRect, int nBottomRect);

        [DllImport("gdi32.dll")]
        static extern IntPtr SelectObject(IntPtr hdc, IntPtr hgdiobj);

        [DllImport("gdi32.dll")]
        static extern int SetBkMode(IntPtr hdc, int iBkMode);

        //
        //
        // Declare variables
        //
        //

        private IntPtr hDC;
        private Graphics g;

        //
        //
        // Public Functions
        //
        //

        public IntPtr createSolidBrushSelect(int _r, int _g, int _b)
        {
            IntPtr _retval = CreateSolidBrush((uint)ColorTranslator.ToWin32(Color.FromArgb(_r, _g, _b)));
            deleteObject(selectObject(_retval));
            return _retval;
        }

        public IntPtr createPen(PenStyle _PenStyle, int _size, uint _color)
        {
            return CreatePen(_PenStyle, _size, _color);
        }

        public IntPtr createPen(PenStyle _PenStyle, int _size, int _r, int _g, int _b)
        {
            return CreatePen(_PenStyle, _size, (uint)ColorTranslator.ToWin32(Color.FromArgb(_r, _g, _b)));
        }

        public IntPtr createPen(PenStyle _PenStyle, int _size, int _r, int _g, int _b, StockObjects _BrushStyle)
        {
            deleteObject(selectObject(GetStockObject(_BrushStyle)));
            return CreatePen(_PenStyle, _size, (uint)ColorTranslator.ToWin32(Color.FromArgb(_r, _g, _b)));
        }

        public IntPtr createPenSelect(PenStyle _PenStyle, int _size, uint _color)
        {
            IntPtr _retval = CreatePen(_PenStyle, _size, _color);
            deleteObject(selectObject(_retval));
            return _retval;
        }

        public IntPtr createPenSelect(PenStyle _PenStyle, int _size, int _r, int _g, int _b)
        {
            IntPtr _retval = CreatePen(_PenStyle, _size, (uint)ColorTranslator.ToWin32(Color.FromArgb(_r, _g, _b)));
            deleteObject(selectObject(_retval));
            return _retval;
        }

        public IntPtr createPenSelect(PenStyle _PenStyle, int _size, int _r, int _g, int _b, StockObjects _BrushStyle)
        {
            deleteObject(selectObject(GetStockObject(_BrushStyle)));
            IntPtr _retval = CreatePen(_PenStyle, _size, (uint)ColorTranslator.ToWin32(Color.FromArgb(_r, _g, _b)));
            deleteObject(selectObject(_retval));
            return _retval;
        }

        public bool deleteObject(IntPtr _hObject)
        {
            return DeleteObject(_hObject);
        }

        public void drawCircle(int _x, int _y, int _radius)
        {
            Ellipse(hDC, _x - _radius, _y - _radius, _x + _radius, _y + _radius);
        }

        public void drawEllipse(int _x, int _y, int _width, int _height)
        {
            Ellipse(hDC, _x - _width / 2, _y - _height / 2, _x + _width / 2, _y + _height / 2);
        }

        public void drawLine(int _startX, int _startY, int _endX, int _endY)
        {
            moveTo(_startX, _startY);
            lineTo(_endX, _endY);
        }

        public void drawRectangle(int _x, int _y, int _width, int _height)
        {
            Rectangle(hDC, _x, _y, _x + _width - 1, _y + _height - 1);
        }

        public void fillScreen(uint _color, int _width, int _height)
        {
            FillRgn(hDC, CreateRectRgn(0, 0, _width, _height), CreateSolidBrush(_color));
        }

        public void getDC(Graphics _g)
        {
            g = _g;
            hDC = g.GetHdc();
        }

        public void lineTo(int _x, int _y)
        {
            LineTo(hDC, _x, _y);
        }

        public void moveTo(int _x, int _y)
        {
            MoveToEx(hDC, _x, _y, IntPtr.Zero);
        }

        public void releaseDC()
        {
            g.ReleaseHdc(hDC);
        }

        public IntPtr selectObject(IntPtr _hObject)
        {
            return SelectObject(hDC, _hObject);
        }
    }
}